package com.example.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Vo.RoleVO;
import com.example.common.annotation.LogAnno;
import com.example.common.result.Result;
import com.example.controller.base.BaseController;
import com.example.entity.Role;
import com.example.entity.RoleMenu;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author daiweiyuan
 * @date 2022/4/5
 */
@RestController
@RequestMapping("/role")
public class RoleController extends BaseController {

    @GetMapping("/page")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result page(int size, int current, String name) {
        Page<Role> rolePage = new Page<>(current, size);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.likeRight(StrUtil.isNotBlank(name), "role_name", name);
        return Result.ok().data(this.roleService.page(rolePage, wrapper));
    }

    @LogAnno(operateType = "新增/编辑角色")
    @PostMapping("/saveOrUpdate")
    @PreAuthorize("hasAnyAuthority('sys:role:add','sys:role:edit')")
    public Result saveOrUpdate(@RequestBody Role role) {
        int id = role.getId() == null ? 0 : role.getId();
        if (roleService.saveOrUpdate(role)) {
            redisService.clearUserAuthorityInfoByRoleId(role.getId());
            return (id > 0) ? Result.update() : Result.created();
        }
        return Result.error();
    }

    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:role:edit')")
    public Result info(@PathVariable Integer id) {
        RoleVO roleVO = new RoleVO();
        Role role = roleService.getById(id);
        List<RoleMenu> roleMenus = roleMenuService.list(new QueryWrapper<RoleMenu>().eq("role_id", id));
        List<Integer> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        BeanUtils.copyProperties(role, roleVO);
        roleVO.setMenuIds(menuIds);
        return Result.ok().data(roleVO);
    }

    @LogAnno(operateType = "删除角色")
    @PostMapping("remove")
    @PreAuthorize("hasAuthority('sys:role:del')")
    public Result remove(@RequestBody List<Integer> ids) {
        if (roleService.removeByIds(ids)) {
            ids.forEach(id->{
                redisService.clearUserAuthorityInfoByRoleId(id);
            });
            return Result.deleted();
        }
        return Result.unDeleted();
    }

    @LogAnno(operateType = "分配权限")
    @PostMapping("/rolePerm/{roleId}")
    @Transactional(rollbackFor = Exception.class)
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public Result perm(@PathVariable Integer roleId, @RequestBody Integer[] menuIds) {
        List<RoleMenu> sysRoleMenus = new ArrayList<>();
        Arrays.stream(menuIds).forEach(menuId -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);
            sysRoleMenus.add(roleMenu);
        });
        roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("role_id", roleId));
        roleMenuService.saveBatch(sysRoleMenus);
        // 清除所有拥有该角色的用户的权限缓存信息
        redisService.clearUserAuthorityInfoByRoleId(roleId);
        return Result.update().message("分配权限成功！").data(menuIds);
    }

    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result list(){
        List<Role> roles = roleService.list();
        return Result.ok().data(roles);
    }
}
